package com.sunseaypw.console;

import java.lang.reflect.Method;


import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringAop2 {
    public static void main(String[] args) throws Exception{
        
        ApplicationContext ctx =new ClassPathXmlApplicationContext("application999.xml");
        var aa = ctx.getBean(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
        System.out.println(aa.getClass());
        var bb = ctx.getBean("InfrastructureAdvisorAutoProxyCreator");
        System.out.println(bb.getClass());
        var cc = ctx.getBean("DefaultAdvisorAutoProxyCreator");
        System.out.println(cc.getClass());
        var dd = ctx.getBean("BeanNameAutoProxyCreator");
        System.out.println(dd.getClass());
        var ee = ctx.getBean("target");
        System.out.println(ee.getClass());        
        var m=ee.getClass().getMethod("find",new Class[]{ String.class });
        m.invoke(ee,"");               
    }
    public static class Target{
        public void find(String aa){
            System.out.println("我的原样输出00000000000000000000000000000");
        }
    }
    @Configuration    
    public static class CodeIoc{
        @Bean("demoAvisor222")
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public DemoAvisor getDemoAvisor() {            
            return new DemoAvisor();
        }
    }
    public static class DemoAvisor implements PointcutAdvisor{
        public org.aopalliance.aop.Advice getAdvice(){
            return new MethodBeforeAdvice() {
                @Override
                public void before(Method method, Object[] args, Object target) throws Throwable {
                    System.out.println("******************************BeforeAdvice目标方法是：" + method.getDeclaringClass().getName() + "."
                            + method.getName());
                }
            };
        } 
        /*isPerInstance()方法官方说暂时还没有应用到，生成的Advisor是单例还是多例不由isPerInstance()的返回结果决定，
          而由自己在定义bean的时候控制。
        */
        public boolean isPerInstance(){
            return true;
        }
        @Override
        public Pointcut getPointcut() {        
            return new Pointcut() {
                @Override
                public ClassFilter getClassFilter() {
                    return ClassFilter.TRUE;
                }
                @Override
                public MethodMatcher getMethodMatcher() {
                    return new MethodMatcher() {
                        @Override
                        public boolean matches(Method method, Class<?> targetClass) {
                            String methodName = method.getName();
                            if ("find".equals(methodName)) {
                                return true;
                            }
                            return false;
                        }
                        @Override
                        public boolean isRuntime() {
                            return false;
                        }
                        @Override
                        public boolean matches(java.lang.reflect.Method arg0, java.lang.Class<?> arg1, java.lang.Object... arg2) {
                            return false;
                        }
                    };
                }
            };
        }
    }
}
